#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <vector>

typedef void (*callback_t)();
// 启停多进程的方案
enum{
    OK,
    USAGE_ERR
};

void Task()
{
    int cnt = 5;
    while(cnt--)
    {
        printf("我是一个子进程，我在完成Task任务,pid: %d, ppid: %d, cnt: %d\n",\
                getpid(), getppid(), cnt);
        sleep(1);
    }
}


void Hello()
{
    int cnt = 5;
    while(cnt--)
    {
        printf("我是一个子进程，我在完成Hello任务,pid: %d, ppid: %d, cnt: %d\n",\
                getpid(), getppid(), cnt);
        sleep(1);
    }
}
void CreateChildProcess(const int& num, std::vector<pid_t> *subs, callback_t cb)
{

    for(int i = 0; i < num; i++)
    {
        pid_t id = fork();
        if(id == 0)
        {
            //child
            cb();
            exit(0);
        }
        //father
        subs->push_back(id);
    }
}
void FatherWaitChid(const std::vector<pid_t> &subs)
{

    for(const auto &pid :subs)
    {
        int status = 0;
        pid_t rid = waitpid(pid, &status, 0);
        if(rid > 0)
        {
            printf("子进程: %d, Exit, exit_code: %d\n",\
                    rid, WEXITSTATUS(status));
        }
    }
}
int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        std::cout << "Usage: " << argv[0] << " process_num" << std::endl;
        exit(USAGE_ERR);
    }
    int num = std::stoi(argv[1]);
    std::vector<pid_t> subs;
    //创建多进程

    CreateChildProcess(num, &subs, Hello);
    
    //父进程等待
    FatherWaitChid(subs);

    return OK;
}



























//typedef void (*callback_t)();
//
//void PrintLog()
//{
//    std::cout << "printf Log" << std::endl;
//}
//
//void SynDisk()
//{
//    std::cout << "write data to disk" << std::endl;
//}
//
//void WriteDataToMysql()
//{
//    std::cout << "write data to mysql" << std::endl;
//}
//int main()
//{
//
//    std::vector<callback_t> tasks;
//    tasks.push_back(PrintLog);
//    tasks.push_back(SynDisk);
//    tasks.push_back(WriteDataToMysql);
//    printf("我是一个进程pid = %d, ppid = %d\n", getpid(), getppid());
//
//    pid_t id = fork();
//
//    if(id < 0)
//    {
//        perror("fork");
//        exit(0);
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt--)
//        {
//            printf("我是子进程pid = %d, ppid = %d\n", getpid(), getppid());
//            sleep(1);
//        }
//        exit(10);
//    }
//    else
//    {
//        //father
//        while(1)
//        {
//       
//            int status = 0;
//            pid_t rid = waitpid(id, &status, WNOHANG);
//            if(rid > 0)
//            {
//                printf("wait success, 退出的子进程是: %d, exit_code: %d\n", rid, WEXITSTATUS(status));
//                break;
//            }
//            else if(rid == 0)
//            {
//                printf("子进程还在运行，还需等待\n");
//                usleep(100000);
//                for(auto &task: tasks)
//                {
//                    task();
//                }
//            }
//            else
//            {
//                perror("waitpid");
//                break;
//            }
//
//        }
//        
//        
//       // int status = 0;
//       // pid_t rid = waitpid(id, &status, 0);
//       // if(rid > 0)
//       // {
//       //     if(WIFEXITED(status))
//       //     {
//       //         printf("wait success, 退出的子进程是: %d, exit_code: %d\n", rid, WEXITSTATUS(status));
//       //     }
//       //     else
//       //     {
//       //         printf("ret = %d\n", rid);
//       //         perror("waitpid");
//       //     }
//       // }
//       // else
//       // {
//       //     perror("waitpid")
//       // }
//    }
//    return 0;
//}
